#include "table.h"
#include "db.h"
#include <fstream>
#include <iostream>
#include <filesystem>
#include "output.h"
#include "util.h"
#include "compare.h"
#include <vector>
#include <set>

namespace fs = std::filesystem;

int table_num = 0;
int row = 0;
int col = 0;

void Create_table(char ins[])
{
    //先读取数据库状态文件和现有表格列表
    read_db();
    read_all_tables();
 
    //解析指令获取表名，记录到总表格数组中
    std::string tablename;
    int i = 13; //移动到指令中name的第一位
    while (ins[i] != ' ')
    {
        tablename += ins[i];
        i++;
    }
    all_table[table_num].table_name = tablename;
 
    i += 1;
    //创建语句
    if (ins[i] == '(') 
    {
        //检测表格名是否重复
        for (int j = 0; j < my_db_num; j++)
        {
            if (my_db[j].table_name == tablename)
            {
                //表格名已存在
                std::cout << "TABLE " << tablename << " 已经存在!" << std::endl;
                return;
            }
        }
        //解析指令获取每一列的属性名，记录到总表格数组中
        i += 1; //移动到指令中column[i]的第一位
        int k = 0;
        std::string col_name[100];
        std::string col_type[100];
        col = 0;
        while (true)
        {    
            if(ins[i+k] == ' '){
                //获取类型
                k++;
                while(ins[i+k] != ',' && ins[i+k] != ')'){
                    col_type[col] += ins[i + k];
                    k++;
                }
            }else{
                col_name[col] += ins[i + k];
                k++;
            }

            if (ins[i + k] == ',')
            {
                //把每列的名字给到对应表格的column数组中，对应列数+1
                int c = all_table[table_num].col_num;
                all_table[table_num].column[c] = col_name[col];
                all_table[table_num].type[c] = col_type[col];
                all_table[table_num].col_num++; 
                col++;
                //移动至下一个列名的第一位
                i = i + k + 1;
                k = 0;
            }
            else if (ins[i + k] == ')')
            {
                //把每列的名字给到对应表格的column数组中，对应列数+1
                int c = all_table[table_num].col_num;
                all_table[table_num].column[c] = col_name[col];
                all_table[table_num].type[c] = col_type[col];
                all_table[table_num].col_num++; col++;
                i = i + k + 1;
                break;
            }  
        }
 
        all_table[table_num].file_name = tablename + ".txt";
 
        //创建表格文件并写入表头
        write_table(table_num, tablename + ".txt");
 
        //修改数据库状态
        my_db[my_db_num].table_name = tablename;
        my_db[my_db_num].file_name = tablename + ".txt";
        my_db[my_db_num].index = table_num;
        my_db_num++;;
        write_db(); //更新数据库状态文件
 
        table_num++; //最后，表格数量加一
 
        //展示最新创建的表头
        std::cout << "--------------------" << std::endl;
        std::cout << "ID ";
        for (int i = 0; i < all_table[table_num - 1].col_num; i++)
        {
            std::cout << all_table[table_num - 1].column[i] + '('+ all_table[table_num - 1].type[i] + ')'<< " ";
        }
        std::cout << std::endl;
        std::cout << "--------------------" << std::endl;
    }
    else
    {
        std::cout << "Error instruction!" << std::endl;
    }
}
//根据指令删除表格
void Drop_table(char ins[])
{
    //先读取数据库状态文件和现有表格列表
    read_db();
    read_all_tables();
 
    //解析指令获取待删除表名
    std::string tablename;
    int i = 11;
    while (ins[i] != '\0')
    {
        tablename += ins[i];
        i++;
    }
 
    bool flag = 1;
    for (int j = 0; j < my_db_num;j++)
    {
        if (my_db[j].table_name == tablename)
        {
            //找到待删的表格，则进行数据迁移
            for (int k = j; k < my_db_num-1; k++)
            {
                my_db[k].table_name = my_db[k+1].table_name;
                my_db[k].file_name = my_db[k+1].file_name;
            }
            table_num--;
            my_db_num--;
            flag = 0;
            std::cout << "删除TABLE成功 !" << std::endl;
            fs::remove(dbPath+"/"+tablename+".txt");
            break;
        }
    }

 
    if (flag == 1) //没找到
    {
        std::cout << "不存在TABLE " << tablename << " !" << std::endl;
        return;
    }
 
    write_db(); //更新数据库状态文件
    read_all_tables(); //修改当前表格列表
}
 
//查看所有表格
void Table_list()
{
    //先读取数据库状态文件和现有表格列表
    read_db();
    read_all_tables();
    printf_table_list();
}
 
//向表格中插入数据
void Insert_table_data(char ins[])
{
    //先读取数据库状态文件和现有表格列表
    read_db();
    read_all_tables();
 
    //解析指令获取表名
    std::string tablename;
    int i = 12; //移动到指令中name的第一位
    while (ins[i] != ' ')
    {
        tablename += ins[i];
        i++;
    }
    all_table[table_num].table_name = tablename;
 
    //根据表名打开对应文件，读取表格数据
    int index;
    std::string filename;
    bool flag = 1;
    for (int j = 0; j < my_db_num; j++)
    {
        if (my_db[j].table_name == tablename)
        {
            //找到了对应的表格
            index = my_db[j].index;
            filename = my_db[j].file_name;
            read_table_data(index, dbPath+"/"+filename);
            flag = 0;
            break;
        }
    }
    if (flag == 1) //没找到
    {
        std::cout << "不存在TABLE " << tablename << " !" << std::endl;
        return;
    }
 
    i += 1; 
    //插入语句
    //INSERT INTO Student VALUES (166661,"张三","计算机科学与技术")
    if (ins[i] == 'V') 
    {
        i += 8; //i移动到value[i]的第一位
        int k = 0;
        std::string col_value[50];
        int num = 0;
        col = 0, row = all_table[index].row_num;
        while (true)
        {   
           
            col_value[num] += ins[i + k];
            k++;
            if(ins[i + k] == '"'){
                k++;
            }

            if (ins[i + k] == ',' )
            {
                //把每列的值给到对应表格的值数组中，对应列数+1
                table_data[row][col] = col_value[num];
                num++; col++;
                //移动至下一个值
                i = i + k + 1;
                k = 0;
                if(ins[i + k] == '"'){
                k++;
            }
            }
            else if (ins[i + k] == ')')
            {
                //把每列的值给到对应表格的值数组中，对应列数+1
                table_data[row][col] = col_value[num];
                num++; col++;
                i = i + k + 1;
                break;
            }
        }
        std::cout << "INSERT SUCCESS !" << std::endl;
        all_table[index].row_num++;
        printf_table(index);
 
        //修改表格文件
        write_table_data(index, dbPath+"/"+filename);
    }
    else
    {
        std::cout << "Error instruction!" << std::endl;
    }
}
 
//删除表格数据
void Delete_table_data(char ins[])
{
    //先读取数据库状态文件和现有表格列表
    read_db();
    read_all_tables();
    
    int i = 7;
    int index = find_table(ins,i);
    std::string filename = all_table[index].file_name;
    //将i移动到name后
    while (ins[i] != '\0' && ins[i] != ' '){
        i++;
    }
    if(i+1 < 100 && ins[i+1] == 'W'){
        std::vector<std::string> parse = where_parse(ins,i+6);
        if(parse.size() != 3){
            std::cout<<"输入WHERE语句参数个数错误 "<<std::endl;
        }

        std::vector<int> datas = compare(parse,index);
        std::set<int> deletes;
        for(int i = 0;i < (int)datas.size();i++){
            deletes.insert(datas[i]);
        }
        for(int i = 0; i < all_table[index].row_num; i++){
            if(deletes.find(i) != deletes.end()){
                for(int m = i;m < all_table[index].row_num ;m++){
                    for(int n = 0;n < all_table[index].col_num;n++){
                        table_data[m][n] = table_data[m+1][n];
                    }    
                }
                all_table[index].row_num--;
            }
        }
        std::cout << "DELETE成功 !" << std::endl;
        printf_table(index);
        write_table_data(index, dbPath+"/"+filename);
    }else if(i+1 < 100 && ins[i+1] != 'W'){
        for(int i = 0; i < all_table[index].row_num; i++){
            for(int j = 0; j < all_table[index].col_num;j++){
                table_data[i][j] = "";
            }  
        }
        all_table[index].row_num = 1;
        std::cout << "DELETE成功 !" << std::endl;
        printf_table(index);
        write_table_data(index, dbPath+"/"+filename);
    }else{
        std::cout<<"语句错误 "<<std::endl;
    }
    
   
}
 
//修改表格数据
void Updata_table_data(char ins[])
{
    //先读取数据库状态文件和现有表格列表
    read_db();
    read_all_tables();
    
    int i = 7;
    int index = find_table(ins,i);
    std::string filename = all_table[index].file_name;
    //将i移动到name后
    while (ins[i] != '\0' && ins[i] != ' '){
            i++;
    }
    //移到set后
    i = i+4;
    // 解析出colname=xxxxx
    std::vector set_col_parse = where_parse(ins,i);
    if(set_col_parse.size() != 3){
        std::cout<<"输入set语句参数个数错误 "<<std::endl;
    }
    //找到那一列
    int col_chosen = -1;
    for(int i = 0 ; i < all_table[index].col_num;i++){
        if(all_table[index].column[i] == set_col_parse[0]) col_chosen = i;
    }
    if(col_chosen == -1) std::cout << "该列不存在 " + set_col_parse[0] << std::endl;
    //解析完set的往后移一位
    ++i;
    //移到where前面那个空格
    while (ins[i] != '\0' && ins[i] != ' '){
            i++;
    }
    if( i+1 < 100 && ins[i+1] == 'W'){
        std::vector<std::string> parse = where_parse(ins,i+6);
            if(parse.size() != 3){
                std::cout<<"输入WHERE语句参数个数错误 "<<std::endl;
            }
    
        std::vector<int> datas = compare(parse,index);
        std::set<int> prints;
        for(int i = 0;i < (int)datas.size();i++){
            prints.insert(datas[i]);
        }
        for (int i = 0; i < all_table[index].row_num; i++){
            if(prints.find(i) != prints.end()) table_data[i][col_chosen] = set_col_parse[2];
        }            
        std::cout << "UPDATE成功 !" << std::endl;
        printf_table(index);
        write_table_data(index, dbPath+"/"+filename);
    }else if(i+1 < 100 && ins[i+1] != 'W'){
        for (int i = 0; i < all_table[index].row_num; i++){
            table_data[i][col_chosen] = set_col_parse[2];
        }            
        std::cout << "UPDATE成功 !" << std::endl;
        printf_table(index);
        write_table_data(index, dbPath+"/"+filename);
    }else{
        std::cout<<"语句错误 "<<std::endl;
    }
    
    
}
 
//选择表格数据并展示
void Selete_table_data(char ins[])
{
    //先读取数据库状态文件和现有表格列表
    read_db();
    read_all_tables();
    
    if (ins[7] == '*')
    {   
        int i = 14;
        //将i移动到tablename后
        while (ins[i] != '\0' && ins[i] != ' ')
        {
            i++;
        }
        int index = find_table(ins,14);
        
        if(i+1 < 100 && ins[i+1] == 'W'){
            std::vector<std::string> parse = where_parse(ins,i+6);
            if(parse.size() != 3){
                std::cout<<"输入WHERE语句参数个数错误 "<<std::endl;
            }
            std::vector<int> datas = compare(parse,index);
            printf_select(index,datas);

        }
        //从TABLE name里选择所有列展示，即展示整个TABLE 
        else if (ins[i] == '\0')
        {
            printf_table(index);
        }
        
    }else{
        //不是全选
        int i = 7;
        std::string colname;
        while(ins[i] != '\0' && ins[i] != ' '){
            colname += ins[i];
            i++;
        }
        i += 6;//移动到name第一个
        int index = find_table(ins,i);
        //将i移动到name后
        while (ins[i] != '\0' && ins[i] != ' ')
        {
            i++;
        }
        //找到要的列
        int col_chosen = -1;
        for(int i = 0 ; i < all_table[index].col_num;i++){
            if(all_table[index].column[i] == colname) col_chosen = i;
        }
        if(col_chosen == -1) std::cout << "该列不存在 " + colname << std::endl;
        //where
        if(i+1 < 100 && ins[i+1] == 'W'){
            std::vector<std::string> parse = where_parse(ins,i+6);
            if(parse.size() != 3){
                std::cout<<"输入WHERE语句参数个数错误 "<<std::endl;
            }
            std::vector<int> datas = compare(parse,index);
            printf_select_col(index,datas,col_chosen);

        }else{
            printf_col(index,col_chosen);
        }
             
    }
}